Skip to content

feat(mac): add BACKEND={llamacpp|mlx} knob for native MLX inference - #4

Open
soobrosa wants to merge 2 commits into
hanxiao:mainfrom
soobrosa:feat/mlx-backend-knob
Open

feat(mac): add BACKEND={llamacpp|mlx} knob for native MLX inference#4
soobrosa wants to merge 2 commits into
hanxiao:mainfrom
soobrosa:feat/mlx-backend-knob

Conversation

@soobrosa

@soobrosa soobrosa commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in BACKEND={llamacpp|mlx} knob to scripts/mac-run.sh so Apple Silicon users can serve Qwen3.6-35B-A3B via mlx-lm for much faster prefill, while keeping llama.cpp as the stable default. New docs/MAC.md documents the tradeoffs and setup.

  • Default unchanged: BACKEND=llamacpp reproduces today's llama.cpp (Metal, GGUF, MTP) path exactly.
  • Opt-in fast path: BACKEND=mlx runs mlx_lm.server from an isolated .venv-mlx on :8080 (same LLAMA_URL), serving models/mlx/Qwen3.6-35B-A3B-UD-MLX-4bit.

Why

Measured on M3 Pro / 36 GB (vs the committed llama.cpp baseline):

Metric llama.cpp mlx-lm Delta
Prefill ~90 t/s ~530 t/s ~6x
Decode ~37 t/s (MTP) ~39 t/s
Greedy parity baseline 9/10 exact (sole diff a synonym) lossless

Prefill dominates the compaction-heavy agent loop, so this is the win that matters for long autonomous jobs.

Notable behaviors (documented in docs/MAC.md)

  • Context auto-cap. Stock mlx_lm.server runs an fp16 KV cache (no --kv-bits flag — upstream ml-explore/mlx-lm#1043). fp16 KV OOMs at ~78–92K actual tokens on 36 GB, so context is auto-capped to MLX_CTX_CAP (75K), comfortably above the default CTX_SIZE of 65536.
  • MODEL_ID pinned. mlx_lm.server resolves the request's model against the loaded model (and otherwise tries HuggingFace), so the script pins MODEL_ID to the model path for this backend. llama.cpp keeps the friendly qwen3.6 label.
  • Dashboard tok/s + KV gauge are llama.cpp-only (/metrics, /slots), so those live widgets stay blank under mlx; jobs run and package normally.

Correctness

Tool-calling (structured tool_calls), streaming, and the agent loop work via the model's bundled chat template. --kv-bits 4 (validated on the non-server path) is greedy-lossless with 15/15 long-context fact recall at 83.5K — it'll come to the server once mlx-lm#1043 lands, after which we flip on quantized KV and raise the cap to ~85K (kv4 ceiling ~92–113K).

Test plan

# default, unchanged
bash scripts/mac-run.sh
# MLX fast path
BACKEND=mlx bash scripts/mac-run.sh

Verified locally: /health ready, tool-calling returns structured tool_calls, SSE streaming works, context auto-cap applied.

Opt-in MLX inference backend alongside the default llama.cpp path. BACKEND=mlx
serves Qwen3.6-35B-A3B via mlx_lm.server for ~6x faster prefill on Apple Silicon,
with context auto-capped to MLX_CTX_CAP (75K) under the fp16-KV OOM ceiling and
MODEL_ID pinned so the agent's requests match the loaded model. Default behavior
is unchanged. docs/MAC.md gains an MLX backend section.

Quantized KV (kv4, ~92-113K ceiling) is pending upstream ml-explore/mlx-lm#1043
(server lacks --kv-bits); once merged, enable it and raise the cap.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@soobrosa
soobrosa force-pushed the feat/mlx-backend-knob branch from de47d77 to c22fcd4 Compare June 5, 2026 16:07
Detects --kv-bits in mlx_lm.server (ml-explore/mlx-lm#1353); when present,
serves with --kv-bits 4 --kv-group-size 64 and raises MLX_CTX_CAP 75K->85K
(verified greedy-lossless + long-ctx recall). Falls back to fp16 KV + 75K cap
on stock mlx-lm, so the change is safe before #1353 ships.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant